﻿using Sunny.UI;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SmartMotion.Core;

namespace SmartMotion.AllPages.SysConfig
{
    public partial class FrmMotionConfig : UIPage
    {
        private List<DllTypeInfo> _motionCanUse;
        private List<DllTypeInfo> _ioCards;
        private ConcurrentDictionary<string, VarInfo> _motionMgr;//已添加运动控制卡
        private ConcurrentDictionary<string, VarInfo> _ioMgr;
        private MotionControlBase _selectedCard;
        private IIOCtrl _selectedIOCard;

        public FrmMotionConfig()
        {
            InitializeComponent();
        }

        private void FrmMotionConfig_Load(object sender, EventArgs e)
        {

            //加载可用的运动控制器
             _motionCanUse = UnityIoc.Ins.LoadDllFromDirectory<MotionControlBase>();
             _motionMgr = GlobalVars.Ins.Vars[GlobalVars.MotionMgr];
             _ioMgr = GlobalVars.Ins.Vars[GlobalVars.IOMgr];

            BindingSource bs = new BindingSource();
            bs.DataSource = _motionCanUse;
            cmbMotionContrlers.DataSource = bs;
            cmbMotionContrlers.DisplayMember = "TypeName";
            //加载可用的IO控制器
            _ioCards = UnityIoc.Ins.LoadDllFromDirectory<IoCtrlBase>();
            BindingSource bs1 = new BindingSource();
            bs1.DataSource = _ioCards;
            cmbIOCards.DataSource = bs1;
            cmbIOCards.DisplayMember = "TypeName";


            //加载以前的运动控制器配置
            lstCards.Items.Clear();
            foreach (var motionItem in _motionMgr.Values)
            {
                if (motionItem.Group == MotionMgr.MotionCard)
                {
                    lstCards.Items.Add(motionItem.Name);
                }
            }
            //加载以前的IO控制器配置
            lstIoCtrl.Items.Clear();
            foreach (var ioCtrler in _ioMgr.Values)
            {
                if (ioCtrler.Group == IOMgr.Ins.IOCtrl)
                {
                    lstIoCtrl.Items.Add(ioCtrler.Name);
                }
            }

        }

        private void btnAddMotion_Click(object sender, EventArgs e)
        {
            DllTypeInfo dllTypeInfo = cmbMotionContrlers.SelectedItem as DllTypeInfo;
            if (dllTypeInfo == null) return;
            var type = Assembly.LoadFile(dllTypeInfo.Dll).GetType(dllTypeInfo.TypeName);
            if (type == null) return;
            List<object> args = new List<object>();
            args.Add((ushort)numMotionCardID.Value);
            MotionControlBase mcb = (MotionControlBase)Activator.CreateInstance(type, args.ToArray());
            string motionCardName = txtMotionCardName.Text;
            if (_motionMgr.ContainsKey(motionCardName))
            {
                ShowErrorDialog("输入了一个已存在的卡名称");
            }
            else
            {
                if (string.IsNullOrEmpty(motionCardName))
                {
                    ShowErrorTip("没有输入卡名称");
                    return;
                }

                _motionMgr.TryAdd(txtMotionCardName.Text, new VarInfo() { Group = "MotionCard", Type = dllTypeInfo.TypeName, Name = txtMotionCardName.Text, Value = mcb });
                lstCards.Items.Add(txtMotionCardName.Text);

                {
                    var axises = mcb.CreateAxisses(numAxisCount.Value);//由运动控制器创建轴，轴的子类
                    mcb.AxisesID.Clear();
                    for (var index = 0; index < axises.Count; index++)
                    {
                        var axisBase = axises[index];
                        axisBase.AxisName = $"{txtMotionCardName.Text}_{ index.ToString().PadLeft(2, '0')}";
                        var varInfo = new VarInfo
                        {
                            Group = txtMotionCardName.Text,
                            Type = axisBase.GetType().FullName,
                            Name = axisBase.AxisName,
                            Value = axisBase
                        };
                        _motionMgr.TryAdd(varInfo.Name, varInfo);
                        mcb.AxisesID.Add(varInfo.VarId);
                    }
                }

           
                _ioMgr.TryAdd(txtMotionCardName.Text, new VarInfo() { Group = "IOCtrl", Type = dllTypeInfo.TypeName, Name = motionCardName, Value = mcb });

                {
                    var inputs = mcb.CreateInputIO(numInput.Value); //由运动控制器创建IO

                    AddIO(txtMotionCardName.Text, inputs, mcb.DIID, "DI");
                }

                {
                    var outputs = mcb.CreateOutputIO(numOutput.Value); //由运动控制器创建IO
                    AddIO(txtMotionCardName.Text, outputs, mcb.DOID, "DO");

                }
                if (numInput.Value > 0 || numOutput.Value > 0)
                {
                    lstIoCtrl.Items.Add(motionCardName);

                }
            }

           

        }


        private void AddIO(string cardName, List<IOIn> ioliList, List<string> idList, string type)
        {
            for (var i = 0; i < ioliList.Count; i++)
            {
                var io = ioliList[i];
                io.Name = $"{cardName}_{type}_{i.ToString().PadLeft(2, '0')}";

                var varInfo = new VarInfo
                {
                    Group = cardName,
                    Type = io.GetType().FullName,
                    Name = io.Name,
                    Value = io
                };
                _ioMgr.TryAdd(varInfo.Name, varInfo);
                idList.Add(varInfo.VarId);
            }
        }

        private void AddIO(string cardName, List<IOOut> ioliList, List<string> ioCardDOID, string type)
        {

            for (var i = 0; i < ioliList.Count; i++)
            {
                var io = ioliList[i];
                io.Name = $"{cardName}_{type}_{i.ToString().PadLeft(2, '0')}";

                var varInfo = new VarInfo
                {
                    Group = cardName,
                    Type = io.GetType().FullName,
                    Name = io.Name,
                    Value = io
                };
                _ioMgr.TryAdd(varInfo.Name, varInfo);
                ioCardDOID.Add(varInfo.VarId);
            }
        }

        private void btnSaveMotion_Click(object sender, EventArgs e)
        {
            MotionMgr.Ins.Save();
        }

        private void lstCards_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstCards.SelectedItem != null)
            {
                string cardName = lstCards.SelectedItem.ToString();
                if (_motionMgr.ContainsKey(cardName))
                {
                    MotionControlBase mcb = _motionMgr[cardName].Value;
                    _selectedCard = mcb;
                    lstAxises.Items.Clear();
                    foreach (var ax in mcb.Axises)
                    {
                        lstAxises.Items.Add(ax.AxisID);
                    }
                    propertyGrid1.SelectedObject = _selectedCard;
                }
            }
        }

        private void lstAxises_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_selectedCard == null) return;
            AxisBase ax = _selectedCard.Axises[lstAxises.SelectedIndex];
            propertyGrid1.SelectedObject = ax;
        }

        private void btnAddIOCtrl_Click(object sender, EventArgs e)
        {
            DllTypeInfo dllTypeInfo = cmbIOCards.SelectedItem as DllTypeInfo;
            if (dllTypeInfo == null) return;
            var type = Assembly.LoadFile(dllTypeInfo.Dll).GetType(dllTypeInfo.TypeName);
            if (type == null) return;
            List<object> args = new List<object> { (ushort)numIoCtrlIndex.Value };
            IoCtrlBase ioCard = (IoCtrlBase)Activator.CreateInstance(type, args.ToArray());

            string ioCardName = txtIoCardName.Text;
            if (_ioMgr.ContainsKey(ioCardName))
            {
                ShowErrorDialog("输入了一个已存在的名称");
            }   
            else
            {
                //讲IO卡添加到全局变量
                _ioMgr.TryAdd(ioCardName,
                    new VarInfo()
                    {
                        Group = IOMgr.Ins.IOCtrl,
                        Type = dllTypeInfo.TypeName,
                        Name = ioCardName,
                        Value = ioCard
                    });
                //讲IO卡添加到列表框
                lstIoCtrl.Items.Add(ioCardName);

                //由IO卡创建输入
                {
                    var inputs = ioCard.CreateInputIO(numIOctrlInput.Value); //由运动控制器创建轴，轴的子类
                    AddIO(txtIoCardName.Text, inputs, ioCard.DIID, "DI");
                }

                //由IO卡创建输出
                {
                    var outputs = ioCard.CreateOutputIO(numIOctrlOutput.Value); //由运动控制器创建轴，轴的子类
                    AddIO(txtIoCardName.Text, outputs, ioCard.DOID, "DO");
                }
            }
        }

        private void lstIoCtrl_SelectedIndexChanged(object sender, EventArgs e)
        {
            string cardName = lstIoCtrl.SelectedItem.ToString();
            if (_ioMgr.ContainsKey(cardName))
            {
                IIOCtrl iocard = _ioMgr[cardName].Value;
                _selectedIOCard = iocard;
                listInput.Items.Clear();
                lstOutput.Items.Clear();
                foreach (var io in iocard.DI)
                {
                    listInput.Items.Add(io);
                }

                listInput.DisplayMember = "Name";
                foreach (var io in iocard.DO)
                {
                    lstOutput.Items.Add(io);
                }

                lstOutput.DisplayMember = "Name";
                propertyGrid2.SelectedObject = _selectedIOCard;
            }
        }

        private void btnSaveIO_Click(object sender, EventArgs e)
        {
            IOMgr.Ins.Save();
        }
    }
}
